<template>
  <div class="weekly">
    <div class="wrapper flex-column">
      <div class="summary flex">
        <p class="tips mr-5">置顶项将在每周一同步至每周计划</p>
        <img
          src="../../assets/images/top.png"
          title="置顶项"
          @click="showTopList"
        />
        <img
          class="ml-10"
          src="../../assets/images/summary.png"
          title="周总结"
          @click="openDrawer"
        />
      </div>
      <div class="title">
        <span>每周计划</span>
      </div>
      <div class="date-picker mt-30 pl-30">
        <a-date-picker
          picker="week"
          v-model:value="week"
          placeholder="选择周"
          @change="weekChange"
        />
        <span class="date-text ml-10">{{ dateText }}</span>
      </div>
      <div class="content-wrap mt-30 flex pl-30">
        <div class="add-weekly-task flex-column">
          <div class="tips">
            <span class="tips-label">tips：</span>
            <span
              >周计划是指需要每天或多天持续进行的、或是每周都要完成的计划，若要填写每日计划
              <a class="click-a" href="/task/daily">点这里</a>
            </span>
          </div>
          <div class="todo-list mt-15 flex-column" :style="todoStyle">
            <div class="flex">
              <a-textarea
                v-model:value="taskText"
                placeholder="按下回车或点击按钮添加计划~"
                @focus="handleFocus"
                @blur="handleBlur"
                @keydown="handleKeyDown"
                auto-size
              ></a-textarea>
              <a-button class="ml-10" type="primary" @click="addTask">
                <template #icon><PlusOutlined /></template>
                添加</a-button
              >
            </div>
            <div class="item-wrap" v-if="todoList && todoList.length !== 0">
              <div class="flex-center" style="height: 100%" v-if="loading">
                <a-spin size="large" tip="Loading..." />
              </div>
              <template v-else>
                <div class="content-progress flex">
                  <div class="content-wrap">
                    <div
                      v-for="(item, index) of todoList"
                      :key="item.id"
                      :class="[
                        'todo-item mt-10 flex p-5',
                        { finish: item.status === 1 },
                      ]"
                      :style="{
                        backgroundColor: item.top === 0 ? '' : '#dadadb',
                      }"
                    >
                      <img
                        v-if="item.top === 0"
                        title="置顶"
                        class="c-p mr-5"
                        src="../../assets/images/itemTop.svg"
                        @click="topItem(item)"
                      />
                      <a-checkbox
                        v-model:checked="item.checked"
                        @change="setTaskStatus(item)"
                      >
                        <div class="label">
                          {{ index + 1 }}、{{ item.task }}；
                        </div>
                      </a-checkbox>
                    </div>
                  </div>
                  <!-- <div class="progress">
                    <a-progress
                      type="circle"
                      :percent="percent"
                      :strokeColor="
                        percent === 100
                          ? '#52c41a'
                          : percent > 50
                          ? '#1677ff'
                          : '#ffc107'
                      "
                      size="small"
                    />
                  </div> -->
                </div>
              </template>
            </div>
            <div v-else class="empty flex-column">
              <div>本周还没有任何计划哦~</div>
              <div class="reference mt-15">
                参考建议：
                <br />
                1、花1-2个小时总结本周；
                <br />
                2、每周坚持锻炼至少2次；
                <br />
                3、加深对一些新技能的学习程度······
              </div>
            </div>
          </div>
        </div>
        <div class="echarts-wrapper flex-column">
          <div class="echarts-title flex">
            <p class="text">当前周【每日计划】完成情况概览</p>
            <a @click="showDialog">查看详情</a>
          </div>
          <div class="echarts-slot mt-15">
            <BaseEcharts :chart-options="options" />
          </div>
        </div>
      </div>
    </div>

    <a-modal
      width="800px"
      v-model:open="dialogConfig.show"
      :title="dialogConfig.title"
      :footer="null"
    >
      <div class="unfinished-detail">
        <div class="wrapper flex">
          <div
            v-for="(item, index) of unfinishedList"
            class="unfinished-item flex-column ml-15 mt-15"
            :key="index"
            style="padding-top: 0"
          >
            <div class="date pl-10">{{ item.date }}</div>
            <div
              v-if="item.list && item.list.length !== 0"
              class="pb-10 pl-10"
              style="flex: 1"
            >
              <div class="flex-center" style="height: 100%" v-if="item.loading">
                <a-spin size="small" tip="Loading..." />
              </div>
              <template v-else>
                <div
                  v-for="(child, childIndex) of item.list"
                  :key="childIndex"
                  :class="['todo-item mt-5', { finish: child.checked }]"
                >
                  <a-checkbox
                    v-model:checked="child.checked"
                    @change="setDailyTaskStatus(child, item)"
                  >
                    <div class="label">
                      <a-tooltip>
                        <template #title>{{ child.content }}</template>
                        <div class="label-text text-ellipsis">
                          {{ childIndex + 1 }}、{{ child.content }}；
                        </div>
                      </a-tooltip>
                    </div>
                  </a-checkbox>
                </div>
              </template>
            </div>
            <div v-else class="finished mt-5 pl-10 pb-5">
              当天计划全部完成啦~
            </div>
          </div>
        </div>
      </div>
    </a-modal>

    <!-- 置顶项 -->
    <a-modal
      width="500px"
      v-model:open="topConfig.show"
      title="【每周计划】置顶内容"
      :footer="null"
    >
      <div class="top-list mt-10">
        <div
          v-for="(item, index) of topConfig.list"
          :key="item.id"
          class="top-list-item mt-10 pt-20"
        >
          <div class="label">{{ index + 1 }}、{{ item.task }}；</div>
          <MinusOutlined
            style="color: #f22"
            class="c-p"
            title="移除"
            @click="removeTop(item, index)"
          />
        </div>
      </div>
    </a-modal>

    <a-drawer
      :width="500"
      title="周总结"
      placement="right"
      :open="drawerShow"
      @close="onClose"
    >
      <template #extra>
        <a-button type="primary" @click="onSave">保存</a-button>
      </template>
      <div class="drawer-wrap flex-column">
        <div class="img-wrap pb-15">
          <div class="label ml-10">
            图片总结：<span class="desc"
              >支持多选，最多6张，可选的类型为png、jpg、jpeg、svg</span
            >
          </div>
          <div class="img-list flex">
            <div
              v-for="item of imgList"
              :key="item.url"
              class="img-item ml-10 mt-10"
            >
              <a-image :src="item.url" />
            </div>
            <div
              class="flex-center mt-10 ml-10"
              style="height: 100%"
              v-if="uploadLoading"
            >
              <a-spin size="large" tip="Loading..." />
            </div>
            <BaseUpload
              v-else
              class="ml-10 mt-10"
              :uploadConfig="{
                multiple: true,
              }"
              @handleUpload="handleUpload"
            >
              <template #labelSlot>
                <PlusOutlined />
              </template>
            </BaseUpload>
          </div>
        </div>
        <div class="text-wrap mt-15 p-10">
          <p class="label mb-15">文字总结：</p>
          <a-textarea
            ref="textareaRef"
            v-if="showTextarea"
            v-model:value="textValue"
            placeholder="给本周做个收尾吧~"
            :auto-size="{ minRows: 2, maxRows: 15 }"
            @blur="textAreaBlur"
          />
          <p class="text" v-else @click="showAreaWrap">
            {{ textValue }}
          </p>
        </div>
      </div>
    </a-drawer>
  </div>
</template>

<script setup>
import {
  onMounted,
  onBeforeUnmount,
  reactive,
  ref,
  computed,
  nextTick,
  createVNode,
} from "vue";
import {
  PlusOutlined,
  ExclamationCircleOutlined,
  MinusOutlined,
} from "@ant-design/icons-vue";
import { message, Modal } from "ant-design-vue";
import dayjs from "dayjs";
import "dayjs/locale/zh-cn";
import isSameOrBefore from "dayjs/plugin/isSameOrBefore";
dayjs.locale("zh-cn");
dayjs.extend(isSameOrBefore);

import {
  getWeeklyPlan,
  addWeeklyPlan,
  updateWeeklyPlan,
  getDailyTotal,
  getWeeklySummarize,
  updateWeeklySummarize,
  topWeeklyPlan,
} from "../../api/plan/weekly";
import { updateDailyPlan } from "../../api/plan/daily";
import { uploadFile } from "../../api/common";
import { calculate } from "../../utils/math";
import { debounce, validateNumber } from "../../utils/util";

const drawerShow = ref(false);
function openDrawer() {
  drawerShow.value = true;
  getWeeklySummarize({
    date: dateText.value.slice(4),
  }).then((res) => {
    if (res.code === 0) {
      if (res.data) {
        textValue.value = res.data.text;
        imgList.value = res.data.url_list
          ? res.data.url_list.split(",").map((item) => ({ url: item }))
          : [];
        showTextarea.value = !textValue.value;
      } else {
        textValue.value = "";
        imgList.value = [];
        showTextarea.value = true;
      }
    }
  });
}
function onClose() {
  Modal.confirm({
    title: () => "关闭周总结",
    icon: () => createVNode(ExclamationCircleOutlined),
    content: () => createVNode("div", {}, "离开前请确认内容是否保存~"),
    okText: "确认",
    cancelText: "取消",
    onOk() {
      drawerShow.value = false;
    },
    onCancel() {
      console.log("Cancel");
    },
  });
}
const onSave = debounce(saveMethod, 1000, true);
function saveMethod() {
  let urlList = imgList.value.map((item) => item.url);
  updateWeeklySummarize({
    urlList,
    text: textValue.value,
    date: dateText.value.slice(4),
  }).then((res) => {
    if (res.code === 0) {
      drawerShow.value = false;
      showTextarea.value = false;
    }
  });
}
const imgList = ref([]);
const uploadLoading = ref(false);
let typeList = ["svg", "png", "jpeg", "jpg"];
function handleUpload(files) {
  uploadLoading.value = true;
  let fileList = Array.from(files).filter((item) => {
    let lastDotIndex = item.name.lastIndexOf(".");
    let type = item.name.slice(lastDotIndex + 1);
    console.log(type, "==");
    return typeList.includes(type);
  });

  if (fileList.length > 6) {
    fileList = fileList.slice(-6);
  }
  let formData = new FormData();
  for (let i = 0; i < fileList.length; i++) {
    formData.append("file", fileList[i]);
  }
  uploadFile(formData).then((res) => {
    if (res.code === 0) {
      let list = res.data.map((item) => ({ url: item }));
      imgList.value.push(...list);
      // 取后6个
      imgList.value = imgList.value.slice(-6);
      uploadLoading.value = false;
    }
  });
}

const showTextarea = ref(true);
const textValue = ref("");
const textareaRef = ref(null);
const textAreaBlur = () => {
  if (!textValue.value) return;
  showTextarea.value = false;
};
const showAreaWrap = () => {
  showTextarea.value = true;
  nextTick(() => {
    textareaRef.value.focus();
  });
};

onMounted(() => {
  weekChange(dayjs(new Date()));

  window.addEventListener("keydown", (e) => {
    if (e.keyCode === 13) {
      isTextareaFocus.value && addTask();
    }
  });
});

onBeforeUnmount(() => {
  window.removeEventListener("keydown", null);
});

const week = ref(dayjs(new Date()));
const dateText = ref(null);
let xAxisList = ref([]);
function weekChange(date) {
  xAxisList.value = [];
  return new Promise((resolve) => {
    let startDate = dayjs(dayjs(date).startOf("week").format("YYYY-MM-DD"));
    let first = startDate;
    let endDate = dayjs(dayjs(date).endOf("week").format("YYYY-MM-DD"));
    while (first.isSameOrBefore(endDate)) {
      xAxisList.value.push(first.format("YYYY-MM-DD"));
      first = first.add(1, "day");
    }
    options.value.xAxis.data = xAxisList.value;
    let text = `${dayjs(date).startOf("week").format("YYYY-MM-DD")} ~ ${dayjs(
      date
    )
      .endOf("week")
      .format("YYYY-MM-DD")}`;
    dateText.value = `已选择：${text}`;
    getList(text);
    resolve(text);
  });
}

function getWeeklyList(date) {
  getWeeklyPlan({
    date,
  }).then((res) => {
    if (res.code === 0) {
      res.data.forEach((item) => {
        item.checked = item.status === 1;
      });
      todoList.value = res.data;
    }
  });
}

function getList(date) {
  getWeeklyList(date);

  getDailyTotal({
    date,
  }).then((res) => {
    if (res.code === 0) {
      totalUnfinishedList.value = res.data.filter((item) => item.status === 0);
      let finishedData = [];
      let unfinishedData = [];
      let rateData = [];
      options.value.xAxis.data.forEach((item) => {
        let num = res.data.filter(
          (data) => data.date === item && data.status === 0
        ).length;
        let num1 = res.data.filter(
          (data) => data.date === item && data.status === 1
        ).length;
        let rate = validateNumber(
          calculate.multiply(100, calculate.divide(num, num + num1)).toFixed(2)
        );
        finishedData.push(num1);
        unfinishedData.push(num);
        rateData.push(rate);
      });
      options.value.series[0].data = finishedData;
      options.value.series[1].data = unfinishedData;
      options.value.series[2].data = rateData;
    }
  });
}

const isTextareaFocus = ref(false);
const handleFocus = () => {
  isTextareaFocus.value = true;
};
const handleBlur = () => {
  isTextareaFocus.value = false;
};
const handleKeyDown = (e) => {
  if (e.keyCode === 13) {
    e.preventDefault();
  }
};
const taskText = ref(null);
const addTask = debounce(addTaskApi, 2000, true);
function addTaskApi() {
  if (!taskText.value) {
    message.warning("你的输入框好像空空如也呢~");
    return;
  }
  const unwantedCharacters = [",", "，", ";", "；", "、", "。", "."];
  let lastChar = taskText.value.slice(-1);
  if (unwantedCharacters.includes(lastChar)) {
    taskText.value = taskText.value.slice(0, -1);
  }
  let date = dateText.value.slice(4);
  addWeeklyPlan({
    task: taskText.value,
    date,
  }).then((res) => {
    if (res.code === 0) {
      taskText.value = "";
      getWeeklyList(date);
    }
  });
}

const todoStatus = {
  finish: {
    color: "#00a3a6",
  },
  todo: {
    color: "#c47ea6",
  },
  empty: {
    color: "transparent",
  },
};
let currentStatus = computed(() => {
  if (todoList.value.length === 0) {
    return "empty";
  } else {
    let some = todoList.value.some((item) => item.status === 0);
    return some ? "todo" : "finish";
  }
});
const todoStyle = computed(() => {
  return {
    borderColor: todoStatus[currentStatus.value].color,
  };
});
const todoList = ref([]);
const percent = computed(() => {
  let list = todoList.value.filter((item) => item.status === 1);
  return Number(((list.length / todoList.value.length) * 100).toFixed(2));
});
const loading = ref(false);
function setTaskStatus(item) {
  loading.value = true;
  updateWeeklyPlan({
    status: item.checked ? 1 : 0,
    id: item.id,
  }).then((res) => {
    loading.value = false;
    if (res.code === 0) {
      message.success(
        item.checked ? "太棒了，又完成了一项计划!" : "是不是不小心点错了呢~"
      );
      getWeeklyList(dateText.value.slice(4));
    }
  });
}

function topItem(item) {
  loading.value = true;
  topWeeklyPlan({
    id: item.id,
    top: 1,
  }).then((res) => {
    loading.value = false;
    if (res.code === 0) {
      message.success("计划已置顶!");
      getWeeklyList(dateText.value.slice(4));
    }
  });
}

function showDialog() {
  unfinishedList.value = [];
  if (totalUnfinishedList.value.length === 0) {
    message.success("当前周【每日计划】完成的很棒!没有剩余计划~");
    return;
  }
  dialogConfig.title = `【${dateText.value.slice(4)}】每日计划完成情况明细`;
  xAxisList.value.forEach((item, index) => {
    unfinishedList.value[index] = {};
    unfinishedList.value[index].date = item;
    let list = totalUnfinishedList.value.filter(
      (unfinished) => unfinished.date === item
    );
    unfinishedList.value[index].list = list;
  });
  dialogConfig.show = true;
}
const options = ref({
  grid: {
    top: "15%",
    left: "6%",
  },
  legend: {
    show: true,
    data: [
      {
        name: "已完成数",
      },
      {
        name: "未完成数",
      },
      {
        name: "未完成率",
      },
    ],
    top: "3%",
    left: "3%",
    itemWidth: 13,
    itemHeight: 12,
    textStyle: {
      lineHeight: 13,
    },
  },
  xAxis: {
    type: "category",
    data: [],
    axisLabel: {
      interval: 0,
    },
  },
  yAxis: [
    {
      type: "value",
      name: "数量",
    },
    {
      type: "value",
      name: "未完成率",
      axisLabel: {
        formatter: "{value}%",
      },
    },
  ],
  tooltip: {
    trigger: "axis",
  },
  series: [
    {
      type: "bar",
      smooth: true,
      symbol: "none",
      color: "#4CAF50",
      name: "已完成数",
      barWidth: 40,
      label: {
        position: "top",
        show: true,
        formatter: (params) => {
          return params.value == "0" ? "" : params.value;
        },
      },
      data: [],
    },
    {
      type: "bar",
      smooth: true,
      symbol: "none",
      color: "#F44336",
      name: "未完成数",
      barWidth: 40,
      label: {
        position: "top",
        show: true,
        formatter: (params) => {
          return params.value == "0" ? "" : params.value;
        },
      },
      data: [],
    },
    {
      type: "line",
      smooth: true,
      symbol: "circle",
      symbolSize: 10,
      yAxisIndex: 1,
      color: "#FF9800",
      lineStyle: {
        width: 3,
      },
      label: {
        show: true,
        formatter: (params) => {
          console.log(params);
          return Number(params.value) === 0 ? "" : params.value + "%";
        },
      },
      name: "未完成率",
      data: [],
    },
  ],
});

const dialogConfig = reactive({
  show: false,
  title: "",
});
const totalUnfinishedList = ref([]);
const unfinishedList = ref([]);
function setDailyTaskStatus(item, fItem) {
  fItem.loading = true;
  updateDailyPlan({
    status: item.checked ? 1 : 0,
    id: item.id,
    date: item.date,
  }).then((res) => {
    fItem.loading = false;
    getList(dateText.value.slice(4));
    if (res.code === 0) {
      if (item.checked) {
        message.success("任何时候去做都不算太晚!");
      } else {
        message.warning("遗留的计划得抓紧啦~");
      }
    }
  });
}

const topConfig = reactive({
  show: false,
  list: [],
});

function showTopList() {
  getWeeklyPlan({
    date: dateText.value.slice(4),
    top: 1,
  }).then((res) => {
    if (res.code === 0) {
      topConfig.list = res.data;
      topConfig.show = true;
    }
  });
}

function removeTop(item, index) {
  topWeeklyPlan({
    id: item.id,
    top: 0,
  }).then((res) => {
    if (res.code === 0) {
      topConfig.list.splice(index, 1);
      message.success("已移除置顶项!");
      getWeeklyList(dateText.value.slice(4));
    }
  });
}
</script>

<style scoped lang="less">
@import "./weekly.less";
</style>
